package utils;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.List;
import java.util.Map;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.alibaba.fastjson.serializer.SerializeConfig;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.serializer.SimpleDateFormatSerializer;
import com.alibaba.fastjson.serializer.ValueFilter;
 
/**
 * @Description：JSON转换工具
 * @Author：luo
 * @Date：2016年6月28日 下午4:55:53
 */
@SuppressWarnings("unused")
public final class FastJsonUtil {
	private static final SerializeConfig config;
	private static final String sdfShort = "yyyyMMdd";
	private static final String sdfLong = "yyyy-MM-dd";
	private static final String sdfLongCn = "yyyy年MM月dd日hh时";
	private static final String sdfLongTime = "yyyyMMddHHmmss";
	private static final String sdfLongTimePlus = "yyyy-MM-dd HH:mm:ss";
	private static final String sdfShortLongTimePlusCn = "yyyy年MM月dd日 HH:mm";
	private static final String sdfLongTimePlusMill = "yyyyMMddHHmmssSSSS";
	private static final String sdfMd = "MM月dd日";
	/**null转换成""*/
	private static final ValueFilter filter = new ValueFilter() {
	    @Override
	    public Object process(Object obj, String s, Object v) {
	    	if(v == null)
	    		return "";
		    return v;
	    }
	};
	static {  
		config = new SerializeConfig();  
		config.put(java.util.Date.class,  new SimpleDateFormatSerializer("yyyy-MM-dd HH:mm:ss"));
//		config.put(Float.class, MyFloatCodec.instance);
//		config.put(Double.class, MyDoubleSerializer.instance);
	}
    private static final SerializerFeature[] features = {
    	SerializerFeature.WriteMapNullValue, // 输出空置字段  
	    SerializerFeature.WriteNullListAsEmpty, // list字段如果为null，输出为[]，而不是null  
	    SerializerFeature.WriteNullNumberAsZero, // 数值字段如果为null，输出为0，而不是null  
	    SerializerFeature.WriteNullBooleanAsFalse, // Boolean字段如果为null，输出为false，而不是null  
	    SerializerFeature.WriteNullStringAsEmpty, // 字符类型字段如果为null，输出为""，而不是null
	    SerializerFeature.WriteDateUseDateFormat,
//	    SerializerFeature.WriteNonStringValueAsString
    };
    
    private static final SerializerFeature[] jsonObjectFeatures = {
    	SerializerFeature.WriteClassName,
		SerializerFeature.WriteMapNullValue,
		SerializerFeature.WriteNullBooleanAsFalse,
		SerializerFeature.WriteNullListAsEmpty,
		SerializerFeature.WriteNullNumberAsZero,
		SerializerFeature.WriteNullStringAsEmpty,
		SerializerFeature.WriteDateUseDateFormat,
		SerializerFeature.WriteEnumUsingToString,
		SerializerFeature.WriteSlashAsSpecial,
    };
	    
    public static <T> void writeJsonToFile(T t, File file) throws IOException {
        String jsonStr = JSONObject.toJSONString(t, SerializerFeature.PrettyFormat);
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file)));
        bw.write(jsonStr);
        bw.close();
    }
 
    public static <T> void writeJsonToFile(T t, String filename) throws IOException {
        writeJsonToFile(t, new File(filename));
    }
 
    public static <T> T readJsonFromFile(Class<T> cls, File file) throws IOException {
        StringBuilder strBuilder = new StringBuilder();
        BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
        String line = null;
        while ((line = br.readLine()) != null) {
            strBuilder.append(line);
        }
        br.close();
        return JSONObject.parseObject(strBuilder.toString(), cls);
    }
 
    public static <T> T readJsonFromFile(Class<T> cls, String filename) throws IOException {
        return readJsonFromFile(cls, new File(filename));
    }
 
    public static <T> T readJsonFromFile(TypeReference<T> typeReference, File file) throws IOException {
        StringBuilder strBuilder = new StringBuilder();
        BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
        String line = null;
        while ((line = br.readLine()) != null) {
            strBuilder.append(line);
        }
        br.close();
        return JSONObject.parseObject(strBuilder.toString(), typeReference);
    }
 
    public static <T> T readJsonFromFile(TypeReference<T> typeReference, String filename) throws IOException {
        return readJsonFromFile(typeReference, new File(filename));
    }

	/**
	 * 把JSON数据转换成较为复杂的java对象列表
	 * @param jsonData
	 *            JSON数据
	 * @return
	 * @throws Exception
	 */
	public static List<Map<String, Object>> toListMap(String jsonData) {
		return JSON.parseObject(jsonData, new TypeReference<List<Map<String, Object>>>(){});
	}
	
	/**
	 * 把json转换成map
	 * @param json
	 * @return
	 */
	public static Map<String,String> toMap(String json){ 
		Map<String,String> map = JSON.parseObject(json,new TypeReference<Map<String,String>>(){}); 
		return map;
	}
	
	/**
	 * 把json转换成map
	 * @param json
	 * @return
	 */
	public static Map<String,Object> toObjMap(String json){ 
		Map<String,Object> map = JSON.parseObject(json,new TypeReference<Map<String,Object>>(){}); 
		return map;
	}
	
	/**
	 * 把json转换为list
	 * @param json
	 * @return
	 */
	public static List<Object> toList(String json){ 
		List<Object> list = JSON.parseObject(json,new TypeReference<List<Object>>(){}); 
		return list;
	}
 
	/**
	 * 把json转换为list 
	 * @param json 
	 * @param clazz 指定的java对象
	 * @return
	 */
    public static <T> List<T> toList(String json, Class<T> clazz) {  
        return JSON.parseArray(json, clazz);  
    } 
	
	/**
	 * 把JSON数据转换成普通字符串列表
	 * @param jsonData
	 *            JSON数据
	 * @return
	 */
	public static List<String> toStringList(String jsonData) {
		return JSON.parseArray(jsonData, String.class);
	}
	
	
	/**
	 * 把JSON数据转换成指定的java对象
	 * @param jsonData
	 *            JSON数据
	 * @param clazz
	 *            指定的java对象
	 * @return
	 */
	public static <T> T toBean(String jsonData, Class<T> clazz) {
		return JSON.parseObject(jsonData, clazz);
	}
	
	/**
	 * object转换为json格式，使用自定义配置
	 * @param object
	 * @return
	 */
	public static String toJson(Object object) { 
        return JSON.toJSONString(object, config,filter, features);  
    }
	
    /**
     * 
     * @param object
     * @return
     */
	public static String toJsonNoFilter(Object object) { 
        return JSON.toJSONString(object, config,features);  
    }
	
	/**
	 * object转换为json格式，默认使用features自带配置
	 * <p>
	 * 空值字符串序列化json后会消失
	 * </p>
	 * @param object
	 * @return
	 */
    public static String toJsonNoFeatures(Object object) {  
        return JSON.toJSONString(object, config);  
    }
    
    /**
	 * object转换为json格式，默认使用Config自带配置
	 * @param object
	 * @return
	 */
    public static String toJsonNoConfig(Object object) {  
        return JSON.toJSONString(object, features);  
    }
    
    /**
     * object转换为json格式，默认使用fastjson自带配置
     * @param object
     * @return
     */
    public static String toJsonDefault(Object object) {  
        return JSON.toJSONString(object);  
    }
    
    /**
     * json转换为数组  
     * @param json
     * @return
     */
    public static <T> Object[] toArray(String json) {  
        return toArray(json, null);  
    }
  
    /**
     * 把json转为数据
     * @param json
     * @param clazz
     * @return
     */
    public static <T> Object[] toArray(String json, Class<T> clazz) {  
        return JSON.parseArray(json, clazz).toArray();  
    }
    
    /**  
     * 将javabean转化为序列化的json字符串  
     * @param obj  
     * @return  
     */  
    public static Object beanToJson(Object obj) {  
        String textJson = JSON.toJSONString(obj);  
        Object objectJson  = JSON.parse(textJson);  
        return objectJson;  
    }
    
    /**  
     * 将string转化为序列化的json字符串  
     * @param stringJson 
     * @return  
     */  
    public static Object strToJson(String stringJson) {  
        Object objectJson  = JSON.parse(stringJson);  
        return objectJson;  
    }
    
    /**  
     * 将map转化为string  
     * @param <V>
     * @param <K>
     * @param m  
     * @return  
     */  
    public static <K,V> String mapToJson(Map<K,V> m) {  
        return JSON.toJSONString(m);  
    }
    
    /**
	 * 将网络请求下来的数据用fastjson处理空的情况,返回""进行转义\"
	 * @param resultJson 返回的json数据
	 * @return
	 */
	public static String dealResponseResult(String resultJson) {
		resultJson = JSONObject.toJSONString(resultJson,jsonObjectFeatures);
		return resultJson;
	}
	
	/**
	 * 将网络请求下来的数据用fastjson处理空的情况,返回""进行转义\",且格式化时间
	 * <p>
	 * 	时间格式默认:yyyy-MM-dd HH:mm:ss
	 * </p>
	 * @param resultJson 返回json
	 * @return
	 */
	public static String toJsonDateFormat(String resultJson) {
		resultJson = JSONObject.toJSONStringWithDateFormat(resultJson,sdfLongTimePlus,jsonObjectFeatures);
		return resultJson;
	}
	/**
	 * 将网络请求下来的数据用fastjson处理空的情况,返回""进行转义\",且格式化时间
	 * @param resultJson 返回json
	 * @param dateFormat 时间格式化
	 * @return
	 */
	public static String toJsonDateFormat(String resultJson,String dateFormat) {
		resultJson = JSONObject.toJSONStringWithDateFormat(resultJson,dateFormat,jsonObjectFeatures);
		return resultJson;
	}
	
	 /** 
     * 返回分页结果json字串 
     * 
     * @param list 
     * @param pageTotal 
     * @param pageSize 
     * @param pageNo 
     * @param <T> 
     * @return json 字串 
     */  
    public static <T> String paginate(List<T> list, int pageTotal, int pageSize, int pageNo) {  
        JSONObject result = new JSONObject();  
        result.put("pageTotal", pageTotal);  
        result.put("pageSize", pageSize);  
        result.put("pageNo", pageNo);  
        result.put("errorCode", 0);  
        result.put("data", list);  
        return JSON.toJSONString(result, features);  
    }  
  
    /** 
     * 返回分页结果的json 
     * 
     * @param params 
     * @param pageTotal 
     * @param pageSize 
     * @param pageNo 
     * @return json 字串 
     */  
    public static String paginate(Map<String, Object> params, int pageTotal, int pageSize, int pageNo) {  
        JSONObject result = new JSONObject();  
        result.put("pageTotal", pageTotal);  
        result.put("pageSize", pageSize);  
        result.put("pageNo", pageNo);  
        result.put("errorCode", 0);  
        result.put("data", params);  
        return JSON.toJSONString(result, features);  
    }  
  
    /** 
     * 返回分页结果的json 
     * 
     * @param params 
     * @param pageTotal 
     * @param pageSize 
     * @param pageNo 
     * @return json 字串 
     */  
    public static String paginateDisableRef(Map<String, Object> params, int pageTotal, int pageSize, int pageNo) {  
        JSONObject result = new JSONObject();  
        result.put("pageTotal", pageTotal);  
        result.put("pageSize", pageSize);  
        result.put("pageNo", pageNo);  
        result.put("errorCode", 0);  
        result.put("data", params);  
        return JSON.toJSONString(result, features);  
    }  
  
    /** 
     * 返回分页结果json字串,去掉fastjson循环引用功能 
     * 
     * @param object    数据对象 
     * @param pageTotal 结果列表总共多少页 
     * @param pageSize  每页多少条记录 
     * @param pageNo    页号 
     * @param count     数据条数 
     * @return json 字串 
     */  
    public static String paginateDisableRef(Object object, int count) {  
        JSONObject result = new JSONObject();  
        result.put("data", object);  
        result.put("count", count);  
        result.put("errorCode", 0);  
        //消除fastjson对同一对象循环引用的问题  
        return JSON.toJSONString(result, features);  
    } 
}